package com.library.uiframework.mvp;

import java.util.HashSet;
import java.util.Set;

import rx.Observable;
import rx.Scheduler;
import rx.Subscriber;
import rx.Subscription;
import rx.android.schedulers.AndroidSchedulers;
import rx.schedulers.Schedulers;

/**
 * @author ran.zhao
 * @version 1.0.0
 * Created by zhaoran on 3/29/16.
 */
public class Executor {
    private static Scheduler sDefaultObserveScheduler = AndroidSchedulers.mainThread();
    private static Scheduler sDefaultSubscriberScheduler = Schedulers.io();

    private final Scheduler mSubscribeScheduler;
    private final Scheduler mObserveScheduler;

    private Set<Subscription> mSubscriptions = new HashSet<>();

    /**
     * Constructor
     */
    public Executor() {
        this(sDefaultSubscriberScheduler, sDefaultObserveScheduler);
    }

    /**
     * Constructor
     *
     * @param subscribeScheduler 被订阅者的执行线程
     * @param observeScheduler   订阅者的观察线程
     */
    public Executor(Scheduler subscribeScheduler, Scheduler observeScheduler) {
        mSubscribeScheduler = subscribeScheduler;
        mObserveScheduler = observeScheduler;
    }

    /**
     * Executes the observable
     *
     * @param observable observable
     * @param subscriber The guy who will be listen to the observable.
     * @param <T>        订阅事件的返回值类型
     * @return Subscription
     */
    public <T> Subscription execute(Observable<T> observable, Subscriber<T> subscriber) {
        Subscription subscription = observable.subscribeOn(mSubscribeScheduler)
                .materialize()
                .observeOn(mObserveScheduler)
                .<T>dematerialize()
                .subscribe(subscriber);

        mSubscriptions.add(subscription);
        return subscription;
    }

    /**
     * unsubscribe all subscribed subscriptions
     */
    public void unsubscribeAll() {
        for (Subscription subscription : mSubscriptions) {
            subscription.unsubscribe();
        }
        mSubscriptions.clear();
    }

    /**
     * init
     *
     * @param subscriberScheduler default post thread
     * @param observerScheduler   default task executor
     */
    public static void init(Scheduler subscriberScheduler, Scheduler observerScheduler) {
        sDefaultSubscriberScheduler = subscriberScheduler;
        sDefaultObserveScheduler = observerScheduler;
    }
}

